package com.oritsh.dicom.scu;

import com.oritsh.dicom.constant.CFindInformationModel;
import com.oritsh.dicom.exception.FindException;
import org.dcm4che.data.Attributes;
import org.dcm4che.data.Tag;
import org.dcm4che.data.VR;
import org.dcm4che.net.DimseRSP;
import org.dcm4che.net.DimseRSPHandler;
import org.dcm4che.net.FutureDimseRSP;
import org.dcm4che.net.pdu.PresentationContext;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: zarra
 * Date: 14-2-5
 * Time: 下午3:20
 * Copyright Shanghai Orient Rain Information Technology Co.,Ltd.
 */
public class FindSCU extends DicomSCU {


    CFindInformationModel model = CFindInformationModel.StudyRoot;
    Attributes keys = new Attributes();

    protected int priority;

    private int cancelAfter;

    public FindSCU(CFindInformationModel model,String aeCalling){
        super(aeCalling);
        this.model = model;
        addLevel(null);
    }

    public FindSCU(String aeCalling){
        this(CFindInformationModel.StudyRoot,aeCalling);
    }

    public FindSCU(){
        this(CFindInformationModel.StudyRoot,"FindSCU");
    }

    private void addLevel(String s) {
        if (s == null)
            s = this.model.level;
        keys.setString(Tag.QueryRetrieveLevel, VR.CS, s);
    }

    @Override
    protected PresentationContext createPresentationContext() {
        return new PresentationContext(1, model.cuid, IVR_LE_FIRST);
    }

    public DimseRSP queryAsync(Attributes keys) throws FindException {
            FutureDimseRSP rsp = new FutureDimseRSP(as.nextMessageID());
            rsp.setAutoCancel(cancelAfter);
            queryAsync(keys,rsp);
            return rsp;
    }

    public void queryAsync(Attributes keys,DimseRSPHandler rspHandler) throws FindException {
        try {
            Attributes dataset = new Attributes();
            dataset.addAll(this.keys);
            dataset.addAll(keys);
            as.cfind(model.cuid, priority, dataset, null, rspHandler);
        } catch (IOException|InterruptedException e) {
            throw new FindException(e.getMessage());
        }
    }

    public Attributes[] find(Attributes keys) throws FindException {
        try {
            List<Attributes> rl = new ArrayList<>();
            DimseRSP rsp = queryAsync(keys);
            while (rsp.next()) {
                Attributes attributes = rsp.getDataset();
                if (attributes != null)
                    rl.add(attributes);
            }
            return rl.toArray(new Attributes[0]);
        } catch (IOException|InterruptedException e) {
            throw new FindException(e.getMessage());
        }
    }

    public CFindInformationModel getModel() {
        return model;
    }

    public void setModel(CFindInformationModel model) {
        this.model = model;
    }
}
